<template>
  <a-modal
    body-class="modal-dialog-wrapper"
    :body-style="{
      maxHeight: 'calc(100vh - 160px)',
      overflow: auto,
    }"
    v-model:visible="showModal"
    title="押金扣款"
    width="80vw"
    unmount-on-close
    @close="onClose"
  >
    <div id="deduct-container" class="relative">
      <a-descriptions :size="'medium'" :align="{ label: 'right' }" style="margin-bottom: 20px">
        <a-descriptions-item :span="1" label="订单编号（自有）">{{ depositInfo.orderCode }}</a-descriptions-item>
        <a-descriptions-item :span="1" label="承租人">{{ depositInfo.memberStr }}</a-descriptions-item>
        <a-descriptions-item :span="1" label="剩余可操作金额">{{ `${depositInfo.availableDepositAmount} 元` }}</a-descriptions-item>
        <a-descriptions-item :span="2" label="已扣款次数"
          >{{ depositInfo.cutPaymentNum }}次，剩余可扣款次数 {{ depositInfo.surplusNum }} 次</a-descriptions-item
        >
      </a-descriptions>
      <page-form :model="form" ref="formRef" layout="vertical">
        <page-form-row :gutter="24">
          <page-form-item
            size="1/3"
            label="选择押金抵扣类型"
            field="typeList"
            :rules="[{ required: true, message: '请选择押金抵扣类型', trigger: 'change' }]"
          >
            <a-select
              v-model="form.typeList"
              placeholder="请选择"
              multiple
              :trigger-props="{ updateAtScroll: true, scrollToClose: true }"
              popup-container="#deduct-container"
              @change="onTypeListChange"
            >
              <a-option v-for="(item, index) of menusTypes" :key="index" :value="item.value" style="width: 100%">{{ item.name }}</a-option>
            </a-select>
          </page-form-item>
          <page-form-item
            size="1/3"
            field="paymentTime"
            label="结算时间"
            :rules="[{ required: true, message: '请选择结算时间', trigger: 'change' }]"
          >
            <i-date-picker
              class="w-full"
              v-model="form.paymentTime"
              show-time
              value-format="YYYY-MM-DD HH:mm:ss"
              :trigger-props="{ updateAtScroll: true, scrollToClose: true }"
              popup-container="#app"
            />
          </page-form-item>
          <page-form-item size="1/3" field="customerName" label="客户名称" :rules="{ required: true, message: '请输入客户名称' }">
            <a-input placeholder="请输入" v-model="form.customerName" :max-length="20" />
          </page-form-item>
        </page-form-row>
        <page-form-row :gutter="24">
          <page-form-item size="1" field="settlementRemark" label="结算备注">
            <a-textarea placeholder="请输入" :max-length="200" v-model="form.settlementRemark" />
          </page-form-item>
        </page-form-row>
        <page-form-row :gutter="24">
          <page-form-item size="1" field="fileIdList" label="上传凭证">
            <upload-img v-model="form.fileIdList" limit="10" />
          </page-form-item>
        </page-form-row>
      </page-form>
      <a-divider style="margin-top: 0" />
      <div style="display: flex; justify-content: space-between">
        <div class="menus">
          <template v-for="(item, index) in menus" :key="index">
            <div v-if="item.visible" :class="['menus-item', item.active ? 'active' : '']" @click="switchMenu(item)">
              {{ item.name }}
            </div>
          </template>
        </div>
        <div class="allAmount" v-if="activeMenu >= 0">
          {{ depositTypeStr }}<span class="blue">{{ allAmount }}</span> 元
        </div>
      </div>
      <!-- 租车费用 -->
      <div class="fee-wrapper" v-if="showModal">
        <!-- 租车费用 -->
        <div v-show="activeMenu == 0">
          <carRentalFee
            ref="carRentalFeeRef"
            :depositInfo="depositInfo"
            v-model:orderFeeList="form.orderFeeList"
            :checkIsExceedFn="checkIsExceedFn"
          />
        </div>
        <!-- 违章费用 -->
        <div v-show="activeMenu == 1">
          <carViolationFee
            ref="carViolationFeeRef"
            :depositInfo="depositInfo"
            v-model:violationFeeList="form.violationFeeList"
            :checkIsExceedFn="checkIsExceedFn"
          />
        </div>
      </div>
    </div>
    <template #footer>
      <a-button @click="onClose">关闭</a-button>
      <a-button type="primary" :loading="okLoading" @click="onConfirm">确认</a-button>
    </template>
  </a-modal>
</template>

<script setup>
  import { ref, computed, nextTick } from 'vue'
  import dayjs from 'dayjs'
  import { decimalAddition } from '@/utils/index'
  import { depositdetailV5, cutPayment } from '@/api/order/sOrder'
  import { Message } from '@arco-design/web-vue'
  import carRentalFee from './car-rental-fee.vue'
  import carViolationFee from './car-violation-fee.vue'

  const form = ref({})
  const emit = defineEmits(['ok'])

  // 抵扣类型字典数据
  const menusTypes = ref([
    { name: '租车费用', value: 0 },
    { name: '违章费用', value: 1 },
  ])
  // 菜单切换
  const menus = ref([
    { name: '租车费用', value: 0, visible: false, active: false },
    { name: '违章费用', value: 1, visible: false, active: false },
  ])
  // 当前选中的菜单
  const activeMenu = computed(() => {
    const active = menus.value.find((e) => e.active)
    if (active) {
      return active.value
    } else {
      return -1
    }
  })
  // 手动切换菜单
  const switchMenu = (item) => {
    // 当前菜单高亮
    menus.value.forEach((menu) => (menu.active = false))
    item.active = true

    loadData()
  }
  // 合计提示文本
  const depositTypeStr = computed(() => {
    if (form.value.typeList && form.value.typeList.length) {
      let temp = []
      if (form.value.typeList.includes(0)) {
        temp.push('租车')
      }
      if (form.value.typeList.includes(1)) {
        temp.push('违章')
      }
      if (temp.length > 0) {
        return `本次需扣款合计(${temp.join('、')})：`
      }
    }
    return `本次需扣款合计：`
  })
  // 弹窗状态
  const showModal = ref(false)
  const depositInfo = ref({})

  // 租车押金费用合计
  const rentalFeeSum = computed(() => {
    let sum = 0
    if (form.value.orderFeeList && form.value.orderFeeList.length) {
      form.value.orderFeeList.forEach((item) => {
        sum = decimalAddition(sum, item.realAmount)
      })
    }
    return sum
  })
  // 违章押金金额合计
  const violationFeeSum = computed(() => {
    let sum = 0
    if (form.value.violationFeeList && form.value.violationFeeList.length) {
      form.value.violationFeeList.forEach((item) => {
        sum = decimalAddition(sum, item.cutPaymentAmount)
      })
    }
    return sum
  })

  // 抵扣合计金额
  const allAmount = computed(() => {
    return decimalAddition(rentalFeeSum.value, violationFeeSum.value)
  })
  /**
   * 校验是否超出
   * @param type 类型 rental 租车 violation 违章
   * @param amount 对应类型的金额合计
   */
  const checkIsExceedFn = (type, amount) => {
    let sum = 0
    if (type == 'rental') {
      sum = decimalAddition(amount, violationFeeSum.value)
    } else if (type == 'violation') {
      sum = decimalAddition(amount, rentalFeeSum.value)
    }
    if (sum > depositInfo.value.availableDepositAmount) {
      Message.warning('剩余可操作金额不足')
      return true
    }
    return false
  }

  // 押金类型选择
  const onTypeListChange = () => {
    // 选中的抵扣类型
    const selTypeList = form.value.typeList
    // 全部visible改为false
    menus.value[0].visible = false
    menus.value[1].visible = false
    // 租车费用
    if (selTypeList.includes(0)) menus.value[0].visible = true
    // 违章费用
    if (selTypeList.includes(1)) menus.value[1].visible = true
    // 选中结果不存在租车费用，清空相关选中数据
    if (!menus.value[0].visible) {
      menus.value[0].active = false
      form.value.orderFeeList = []
      carRentalFeeRef.value && carRentalFeeRef.value.reset()
    }
    // 选中结果不存在租车费用，清空相关选中数据
    if (!menus.value[1].visible) {
      menus.value[1].active = false
      form.value.violationFeeList = []
      carViolationFeeRef.value && carViolationFeeRef.value.reset()
    }
    // 存在选中结果时，默认高亮并加载数据
    if (selTypeList.length > 0) {
      // 默认租车费用和违章费用都没有选中
      const hasActive = menus.value.some((item) => item.active)
      // 均为选中的情况下，第一个开启的菜单默认选中
      if (!hasActive) {
        const firstVisible = menus.value.find((item) => item.visible)
        firstVisible.active = true
      }

      // 加载数据
      loadData()
    } else {
      menus.value.forEach((item) => (item.active = false))
    }
  }

  // 加载数据
  const carRentalFeeRef = ref(null)
  const carViolationFeeRef = ref(null)
  const loadData = () => {
    nextTick(() => {
      // 当前选中租车费用
      if (activeMenu.value == 0) {
        carRentalFeeRef.value.loadData()
      }
      // 当前选中违章费用
      if (activeMenu.value == 1) {
        carViolationFeeRef.value.loadData()
      }
    })
  }

  //确定
  const okLoading = ref(false)
  const formRef = ref()
  const onConfirm = () => {
    formRef.value.validate((error) => {
      if (!error) {
        okLoading.value = true
        if (allAmount.value <= 0) {
          Message.error('本次押金合计抵扣金额需大于0')
          okLoading.value = false
          return false
        }
        cutPayment({
          ...form.value,
          depositId: depositInfo.value.id,
        })
          .then(() => {
            emit('ok')
            Message.success('操作成功')
            onClose()
          })
          .catch(() => {
            const orderId = depositInfo.value.orderId
            onClose()
            show(orderId)
          })
          .finally(() => {
            okLoading.value = false
          })
      }
    })
  }

  /**
   * 开启弹窗
   * @param orderId 订单id
   */
  const show = (orderId) => {
    showModal.value = true
    depositdetailV5({
      orderId: orderId,
      orderType: 1, //1 短租 0 长租
    }).then((res) => {
      depositInfo.value = res.result
      // 默认值
      form.value.paymentTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
      form.value.customerName = depositInfo.value.memberName
    })
  }
  /**
   * 关闭弹窗
   */
  const onClose = () => {
    showModal.value = false
    form.value = {}
    depositInfo.value = {}

    menus.value[0].visible = false
    menus.value[0].active = false

    menus.value[1].visible = false
    menus.value[1].active = false

    carRentalFeeRef.value && carRentalFeeRef.value.reset()
    carViolationFeeRef.value && carViolationFeeRef.value.reset()
  }
  defineExpose({ show, onClose })
</script>

<style lang="less" scoped>
  .menus {
    display: flex;
    justify-content: flex-start;
    align-items: center;
    margin-bottom: 20px;
    .menus-item {
      color: #4e5969;
      font-size: 28rpx;
      padding: 5px 16px;
      margin-right: 12px;
      font-weight: 400;
      cursor: pointer;
    }
    .active {
      border-radius: 30px;
      color: #1890ff;
      font-weight: 500;
      background: #f2f3f5;
    }
  }
  .allAmount {
    font-family: PingFang SC, PingFang SC;
    font-weight: 600;
    font-size: 20px;
    color: #1d2129;
    text-align: left;
    font-style: normal;
    text-transform: none;
  }
  .blue {
    color: #1890ff;
  }
</style>
